package com.dream.stock.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.dream.app.service.OrgService;
import com.dream.dao.master.ProductPartDAO;
import com.dream.dao.master.ShopDAO;
import com.dream.dao.stock.ProductPartRequestDAO;
import com.dream.dao.stock.ProductPartStockDAO;
import com.dream.dao.stock.StockExpressDAO;
import com.dream.master.service.ShopService;
import com.dream.model.app.AppAbstractUser;
import com.dream.model.master.ProductPart;
import com.dream.model.master.Shop;
import com.dream.model.stock.ProductPartRequest;
import com.dream.model.stock.ProductPartRequest.RequestStatus;
import com.dream.model.stock.ProductPartRequest.StockDirection;
import com.dream.model.stock.ProductPartStock;
import com.dream.model.stock.ProductPartStock.StockProductType;
import com.dream.model.stock.StockExpress;
import com.dream.model.stock.StockExpress.ExpressStatus;
import com.dream.stock.service.StockService;
import com.dream.utils.hibernate.PagingVO;
import com.dream.vo.stock.PartRequestVO;
import com.dream.vo.stock.ProductPartStockVO;
import com.dream.vo.stock.StockExpressVO;
import com.google.common.collect.Lists;

@Service("stockService")
public class StockServiceImpl implements StockService {

	@Autowired
	private ProductPartStockDAO productPartStockDAO;
	
	@Autowired
	private ProductPartDAO productPartDAO;
	
	@Autowired
	private ProductPartRequestDAO productPartRequestDAO;
	
	@Autowired
	private ShopService shopService;
	
	@Autowired
	private OrgService orgService;
	
	@Autowired
	private StockExpressDAO stockExpressDAO;
	
	@Autowired
	private ShopDAO shopDAO;
	
	@Override
	@Transactional
	public PagingVO queryReqHistory(ProductPartStockVO vo, PagingVO page,AppAbstractUser user) {
		
		List<Long> leafOrgs = orgService.getLeafOrgs(vo.getFirstOrg(), vo.getSecondOrg());
		vo.setOrgs(leafOrgs);
		
		return productPartRequestDAO.queryHistory(vo, page);
	}

	@Override
	@Transactional
	public List<ProductPartStock> searchProductPart(ProductPartStockVO vo) {
		
		final int topN = 10;
		List<ProductPartStock> stocks = productPartStockDAO.getProductPart(vo,topN);
		//入库
		if(vo.getRequestType().equals(StockDirection.in.name())){
			//没有库存 初始化0
			if(CollectionUtils.isEmpty(stocks)){
				List<ProductPart> parts = productPartDAO.searchProductPart(vo.getProductPartId(), vo.getProductPartName(),topN);
				if(CollectionUtils.isNotEmpty(parts)){
					
					stocks = Lists.newArrayList();
					for(ProductPart item : parts){
						
						ProductPartStock stock = new ProductPartStock();
						stock.setProductPart(item);
						stocks.add(stock);
					}
				}
			}
			
		}
		
		return stocks;
	}

	@Override
	@Transactional
	public void submitInStock(ProductPartStockVO vo, AppAbstractUser user) {
		
		List<ProductPartRequest> list = vo.populate(user.getId());
		productPartRequestDAO.saveOrUpdateBatch(list);
		//出库立马减库存 拒绝后 回滚库存
		if(vo.getRequestType().equals(StockDirection.out.name())){
			if(CollectionUtils.isNotEmpty(list)){
				for(ProductPartRequest item : list)
					adjustStock(user,item.getStockType(),item.getToShopId(),item.getProductPartId(),-item.getRequestNum());
			}
		}
	}

	@Override
	@Transactional
	public PagingVO queryRequest(ProductPartStockVO vo,PagingVO page,AppAbstractUser user) {
		
		List<String> shops = shopService.queryMyShopId(user);
		if(CollectionUtils.isEmpty(shops)){
			return page;
		}
		vo.setMyShops(shops);
		return productPartRequestDAO.query(vo, page);
	}

	@Override
	@Transactional
	public void doActionRequest(String type, PartRequestVO vo, AppAbstractUser user) {
		
		if(ArrayUtils.isNotEmpty(vo.getRequestId())){
			RequestStatus status = RequestStatus.getInstance(type);
			int i=0,size = vo.getRequestId().length;
			for(Long id : vo.getRequestId()){
				ProductPartRequest req = productPartRequestDAO.selectById(id);
				req.setUpdateTime(new Date());
				req.setUpdateUser(user.getId());
				req.setStatus(status);
				if(vo.getAppItemComment() != null && size == vo.getAppItemComment().length){
					req.setApproveCommont(vo.getAppItemComment()[i]);
				}
				
				if(vo.getRcvCommentItem() != null && size == vo.getRcvCommentItem().length){
					req.setRcvComment(vo.getRcvCommentItem()[i]);
				}
				
				if(vo.getUnnormalType() != null && size == vo.getUnnormalType().length){
					if(StringUtils.isNotBlank(vo.getUnnormalType()[i]))
						req.setUnnormalType(Long.parseLong(vo.getUnnormalType()[i]));
				}
				
				if(vo.getUnnormalNum() != null && size == vo.getUnnormalNum().length){
					if(StringUtils.isNotBlank(vo.getUnnormalNum()[i]))
						req.setUnnormalNum(Integer.parseInt(vo.getUnnormalNum()[i]));
				}
				
				
				productPartRequestDAO.saveOrUpdate(req);
				productPartRequestDAO.flushAndClear();
				//收货 增加库存
				if(status.equals(RequestStatus.received)){
					if(req.getRequestType().equals(StockDirection.in)){
						adjustStock(user, req.getStockType(),req.getToShopId(),req.getProductPartId(),req.getRequestNum());
					}
					receiveExpress(user, req);
					
				}
				
				//部分收货
				if(status.equals(RequestStatus.other)){
					if(req.getRequestType().equals(StockDirection.in)){
						int rest = req.getRequestNum()-req.getUnnormalNum();
						if(rest>0){
							adjustStock(user, req.getStockType(),req.getToShopId(),req.getProductPartId(),rest);
						}
					}
					receiveExpress(user, req);
				}
				
				
				//拒绝 回滚库存
				if(status.equals(RequestStatus.reject)){
					if(req.getRequestType().equals(StockDirection.out))
						adjustStock(user, req.getStockType(),req.getToShopId(),req.getProductPartId(),req.getRequestNum());
				}
				i++;
			}
		}
		
	}

	private void receiveExpress(AppAbstractUser user, ProductPartRequest req) {
		Long expressId = req.getExpressId();
		StockExpress express = stockExpressDAO.selectById(expressId);
		express.setStatus(ExpressStatus.received);
		express.setUpdateTime(new Date());
		express.setUpdateUser(user.getId());
		express.setReceiveTime(new Date());
		stockExpressDAO.saveOrUpdate(express);
	}
	
	@Transactional
	private void adjustStock(AppAbstractUser user,StockProductType stockType, String shopId,String partId,int num) {
		
		ProductPartStock stock = productPartStockDAO.getStock(stockType, shopId, partId);
		if(stock != null){
			stock.setUpdateTime(new Date());
			stock.setUpdateUser(user.getId());
			stock.setStock(stock.getStock()+num);
			productPartStockDAO.saveOrUpdate(stock);
			
		}else if(num > 0){
			
			stock = new ProductPartStock();
			stock.setCreateTime(new Date());
			stock.setCreateUser(user.getId());
			stock.setStockType(stockType);
			stock.setShopId(shopId);
			stock.setProductPartId(partId);
			stock.setStock(num);
			
			productPartStockDAO.save(stock);
			
		}
		productPartStockDAO.flushAndClear();
	}

	@Override
	@Transactional
	public PagingVO queryMyStock(ProductPartStockVO vo, PagingVO page, AppAbstractUser user) {
		
		List<String> shops = shopService.queryMyShopId(user);
		if(CollectionUtils.isEmpty(shops)){
			return page;
		}
		vo.setMyShops(shops);
		return productPartStockDAO.query(vo, page);
	}

	@Override
	@Transactional
	public PagingVO queryAllStock(ProductPartStockVO vo, PagingVO page, AppAbstractUser user) {
		

		List<Long> leafOrgs = orgService.getLeafOrgs(vo.getFirstOrg(), vo.getSecondOrg());
		vo.setOrgs(leafOrgs);
		
		return productPartStockDAO.query(vo, page);
	}

	@Override
	@Transactional
	public void updateStock(String id, Integer number, AppAbstractUser user) {
		
		ProductPartStock stock = productPartStockDAO.selectById(id);
		if(number >= 0){
			stock.setStock(number);
			stock.setUpdateTime(new Date());
			stock.setUpdateUser(user.getId());
			productPartStockDAO.saveOrUpdate(stock);
		}
	}

	@Override
	@Transactional
	public ProductPartRequest getRequest(Long id) {
		return productPartRequestDAO.selectById(id);
	}

	@Override
	@Transactional
	public void updatePost(StockExpressVO vo, AppAbstractUser user) {
		
		StockExpress exp = new StockExpress();
		vo.populate(exp);
		exp.setStatus(ExpressStatus.post);
		exp.setDeleted(false);
		exp.setPostTime(new Date());
		exp.setCreateTime(new Date());
		exp.setCreateUser(user.getId());
		Long id = (Long)stockExpressDAO.save(exp);
		
		ProductPartRequest request = productPartRequestDAO.selectById(vo.getRequestId());
		request.setExpressId(id);
		request.setStatus(RequestStatus.post);
		productPartRequestDAO.saveOrUpdate(request);
		
	}

	@Override
	@Transactional
	public StockExpress getExpress(Long id) {
		
		return stockExpressDAO.selectById(id);
	}

	@Override
	@Transactional
	public void initStockData(String partId) {
		
		List<Shop> list = shopDAO.queryAllWarehouse();
		if(CollectionUtils.isNotEmpty(list)){
			for(Shop item : list){
				ProductPartStock stock = productPartStockDAO.getStock(StockProductType.new_product, item.getId(), partId);
				if(stock == null){
					stock = new ProductPartStock();
					stock.setProductPartId(partId);
					stock.setShopId(item.getId());
					stock.setStockType(StockProductType.new_product);
					stock.setStock(0);
					stock.setDeleted(false);
					stock.setCreateTime(new Date());
					productPartStockDAO.save(stock);
				}
			}
		}
		
	}
	
}
	

